package com.woniuxy.school.online.repair.service.impl;

import com.woniuxy.commons.core.exception.SchoolException;
import com.woniuxy.commons.core.model.Result;
import com.woniuxy.school.online.repair.entity.*;
import com.woniuxy.school.online.repair.from.AddRepairForm;
import com.woniuxy.school.online.repair.mapper.RepairAttachmentMapper;
import com.woniuxy.school.online.repair.mapper.RepairInfoMapper;
import com.woniuxy.school.online.repair.mapper.UserProjectMapper;
import com.woniuxy.school.online.repair.mongomapper.RepairTracking;
import com.woniuxy.school.online.repair.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniuxy.school.online.repair.util.AMapUtils;
import com.woniuxy.school.user.client.UserInfoClient;
import com.woniuxy.school.user.entity.UserInfo;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * <p>
 * 维修表 服务实现类
 * </p>
 *
 * @author 吴彦祖
 * @since 2025年05月13日
 */
@Service
public class RepairInfoServiceImpl extends ServiceImpl<RepairInfoMapper, RepairInfo> implements RepairInfoService {
    @Autowired
    private UserInfoClient userInfoClient;
    @Autowired
    private AreaService areaService;
    @Autowired
    private UserProjectAreaService userProjectAreaService;
    @Autowired
    private UserProjectService userProjectService;
    @Autowired
    private RepairInfoService repairInfoService;
    @Autowired
    private RepairLogService repairLogService;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private RepairAttachmentMapper repairAttachmentMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    @Autowired
    private UserProjectMapper userProjectMapper;

    /**
     * 新增保修录入
     * 通过电话查询用户是否存在
     * 通过区域编码查询维修区域
     * 通过区域编码查询项目人员区域关系表
     * 判断该区域是否有区域的项目
     * 判断预约维修时间
     * 判断地址是否输入正确
     * 通过项目ID查询维修项目
     * 上传文件,返回文件地址
     * 新增到保修文件表
     * 新增到报修表
     * 新增报修记录
     * 将用户的报修列表记录到mongodb
     */
    @Override
    @Transactional
    public boolean addRepair(AddRepairForm addRepairForm, String token) {
        //通过电话查询用户是否存在
        Result<UserInfo> userInfoResult = userInfoClient.getUserInfoByPhone(addRepairForm.getPhone());
        if (userInfoResult.getCode() != 200) throw new SchoolException(4011, "请求失败");
        if (userInfoResult.getData() == null) throw new SchoolException(1234, "不存在该电话的用户");
        //通过区域编码查询维修区域
        Area area = areaService.getById(addRepairForm.getAreaId());
        if (area == null) throw new SchoolException(1235, "该区域不存在");
        if (area.getState() == 2) throw new SchoolException(1237, "该区域已禁用");
        //通过区域编码查询项目人员区域关系表
        List<UserProjectArea> userProjectAreas = userProjectAreaService.query().eq("area_code", area.getAreaCode()).list();
        if (userProjectAreas == null || userProjectAreas.size() <= 0) throw new SchoolException(1236, "人员区域关系不存在");
        //判断该区域是否有区域的项目
        if (!userProjectAreas.stream().map(userProjectArea -> userProjectArea.getRelationId()).collect(Collectors.toList()).contains(addRepairForm.getUserProjectId()))
            throw new SchoolException(1240, "该区域不存在该项目");
        //判断预约维修时间
        if (addRepairForm.getPreTime().isBefore(LocalDateTime.now())) throw new SchoolException(1242, "预约时间不能低于当前时间");
        //判断地址是否输入正确
        try {
            AMapUtils.getLngLat(addRepairForm.getAddress());
        } catch (Exception e) {
            throw new SchoolException(1243, "地址输入错误");
        }
        //通过项目ID查询维修项目
        UserProject userProject = userProjectService.getById(addRepairForm.getUserProjectId());
        if (userProject != null && userProject.getState() == 2) throw new SchoolException(1242, "该维修项目已禁用");
        //新增到报修表
        RepairInfo repairInfo = new RepairInfo();
        repairInfo.setRepairNum(UUID.randomUUID().toString());
        repairInfo.setRepairDate(addRepairForm.getPreTime()); //预约时间
        repairInfo.setRepairArea(area.getAreaCode());
        repairInfo.setDetailLocation(addRepairForm.getAddress());
        repairInfo.setRepairProjectOne(Objects.requireNonNull(userProject).getRepairProject());
        repairInfo.setRepairContent(addRepairForm.getRepairContent());
        UserInfo userInfo = userInfoResult.getData();
        repairInfo.setRepairUser(Long.parseLong(String.valueOf(Objects.requireNonNull(userInfo).getId())));
        repairInfo.setRepairUserName(userInfo.getUserName());
        repairInfo.setUserPhone(userInfo.getPhone());
        repairInfo.setRepairState(1); //待受理
        repairInfo.setCreateUser(Long.parseLong(String.valueOf(userInfo.getId())));
        repairInfo.setCreateDate(LocalDateTime.now());
        repairInfo.setIsMaterial(2); //无
        if (addRepairForm.getRepairId() == null) {
            repairInfoService.getBaseMapper().insert(repairInfo);
        } else {
            repairInfo.setId(addRepairForm.getRepairId());
            RepairInfo RepairInfoById = repairInfoService.getBaseMapper().selectById(addRepairForm.getRepairId());
            if (RepairInfoById == null) throw new SchoolException(1249, "不存在该维修记录，无法重新提交");
            repairInfoService.getBaseMapper().updateById(repairInfo);
        }
        //上传文件,返回文件地址
        //List<RepairAttachment> repairAttachments = UploadUtil.uploadImages(addRepairForm.getImages(), userInfo.getId(), repairInfo.getRepairNum());
        //新增到报修文件表
        //repairAttachmentMapper.addAllRepairAttachments(repairAttachments);
        //新增报修记录
        RepairLog repairLog = new RepairLog();
        repairLog.setRepairNum(repairInfo.getRepairNum());
        repairLog.setRepairState(repairInfo.getRepairState());
        repairLog.setOperUser(repairInfo.getRepairUser());
        repairLog.setOperDate(repairInfo.getCreateDate());
        repairLog.setOperContent(repairInfo.getRepairContent());
        int insert = repairLogService.getBaseMapper().insert(repairLog);
        if (insert >= 1) {
            //将用户的报修列表记录到mongodb
            RepairTracking repairTracking = new RepairTracking();
            repairTracking.setUserId(String.valueOf(userInfo.getId()));
            repairTracking.setRepairType("报修");
            repairTracking.setContent(userInfo.getUserName() + "于" + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + "通过报修");
            repairTracking.setRepairTime(LocalDateTime.now());
            mongoTemplate.save(repairTracking);
            //发送报修记录ID到队列
            rabbitTemplate.convertAndSend("repairExchange", "repairKey", repairInfo.getId(), message -> {
                message.getMessageProperties().setMessageId(UUID.randomUUID().toString());
                message.getMessageProperties().setContentEncoding("UTF-8");
                return message;
            });

        }
        return insert >= 1;
    }

    /**
     * 管理员审核报修记录
     *
     * @param repairId 维修记录的ID  eyJhbGciOiJIUzM4NCJ9.eyJleHAiOjE3NDc0ODQ3MTV9.jbKzPQPfiU9IIi8133IgU4WqMmK1VXH-paqL6WE4cR3nU6k_E0ng18yFXsGljLGT
     */
    public void checkRepair(Long repairId, String token) {
        //查询维修记录
        RepairInfo repairInfo = repairInfoService.getBaseMapper().selectById(repairId);
        if (repairInfo == null) throw new SchoolException(1345, "不存在该维修记录");
        //判断维修状态
        if (repairInfo.getRepairState() != 1 && repairInfo.getRepairState() != 6)
            throw new SchoolException(1346, "待审核或者已驳回的维修记录才能审核");
        //修改维修记录状态为带派工 1.待受理  2.带派工  3.待批准  4.维修中  5.待决算  6.已驳回 7.已关闭',
        repairInfo.setRepairState(2);
        repairInfoService.updateById(repairInfo);
    }

    /**
     * 通过维修项目查询可用的维修员
     * 通过维修记录ID查询维修记录
     * 通过区域编码查询区域
     * 通过区域编码查询区域人员关系
     * 根据维修项目匹配该区域的人员
     */
    @Override
    public List<UserProject> getUsdRepairUser(Long repairId) {
        //通过维修记录ID查询维修记录
        RepairInfo repairInfo = repairInfoService.getBaseMapper().selectById(repairId);
        if (repairInfo == null) throw new SchoolException(2567, "该维修记录不存在");
        if (repairInfo.getRepairState() != 2) throw new SchoolException(2568, "非待派工状态的维修记录不能派工");
        //通过区域编码查询区域
        Area area = areaService.query().eq("area_code", repairInfo.getRepairArea()).one();
        if (area.getState() == 2) throw new SchoolException(2568, "该区域被禁用");
        //通过区域编码查询区域人员关系
        List<UserProjectArea> areaList = userProjectAreaService.query().eq("area_code", area.getAreaCode()).list();
        if (areaList != null && areaList.size() > 0) {
            //根据维修项目匹配该区域的人员
            return userProjectService.query().in("id", areaList.stream().map(userProjectArea -> userProjectArea.getRelationId()).collect(Collectors.toList())).eq("repairProject", repairInfo.getRepairProjectOne()).eq("state", 1).list();
        }
        return null;
    }

    /**
     * 审核人员给维修记录指定维修员
     * <p>
     * 查询维修记录信息
     * 查询维修人员
     * 将维修人员记录到维修记录
     * 将用户的报修列表记录到mongodb
     */
    @Override
    @Transactional
    public void addRepairUser2Repair(Long repairId, Long repairPerson) {
        //查询维修记录信息
        RepairInfo repairInfo = repairInfoService.getBaseMapper().selectById(repairId);
        if (repairInfo == null) throw new SchoolException(4123, "维修记录不存在");
        if (repairInfo.getRepairState() != 2) throw new SchoolException(4129, "待派工的维修记录才能派工");
        if (repairInfo.getRepairPerson() != null) throw new SchoolException(4128, "该维修记录已经派工");
        //查询维修人员
        UserProject userProject = userProjectService.query().eq("repairUser", repairPerson).one();
        if (userProject == null) throw new SchoolException(4122, "维修人员不存在");
        //更改维修员状态为禁用editRepairState2
        int update = userProjectMapper.editRepairState2(repairInfo.getRepairUser());
        if (update <= 0) throw new SchoolException(4129, "该维修人员已被派工");
        //将维修人员记录到维修记录
        repairInfo.setRepairPerson(String.valueOf(repairPerson));
        repairInfoService.getBaseMapper().updateById(repairInfo);
        //将用户的报修列表记录到mongodb
        RepairTracking repairTracking = new RepairTracking();
        repairTracking.setUserId(String.valueOf(repairInfo.getRepairUser()));
        repairTracking.setRepairType("派工");
        repairTracking.setContent("受理人【" + repairInfo.getAcceptUser() + "】指派维修工【" + userProject.getRepairUserName() + "】承修。");
        repairTracking.setRepairTime(LocalDateTime.now());
        mongoTemplate.save(repairTracking);
    }
}
